Documentacao Tecnica — Modulo Seller
Versao: 1.1.0 | Release: Seller v1.1
Stack: ADVPL sobre TOTVS Protheus
Autor: Jose Antonio
1. Visao Geral
O modulo Seller e responsavel pela integracao de Notas Fiscais de Venda
e Devolucao entre o ERP Protheus e o sistema externo Campos Dealer. O fluxo
consiste em extrair notas pendentes, transforma-las em payloads JSON, envia-las
via REST e auditar cada operacao na tabela ZRM.
1.1 Componentes (8 arquivos PRW)
| Arquivo | Responsabilidade | Prefixo |
|---|
sellMain.prw | Orquestrador de fluxos (vendas, devolucoes, schedule) | SHSELL |
sellCfg.prw | Configuracao, ambiente RPC, credenciais, MVs | SHCFG |
sellQry.prw | Extracao de notas via SQL (anti-join ZRM) | SHQRY |
sellBld.prw | Transformacao: agrupamento e construcao JSON | SHBLD |
sellSnd.prw | Envio REST para Campos Dealer | SHSEND |
sellLog.prw | Auditoria: gravacao na tabela ZRM | SHLOG |
sellRep.prw | Reprocessamento de notas pendentes | SHREP |
sellSta.prw | Monitoramento: console (FWMBrowse) | SHSTA / SHMON |
1.2 Diagrama de Componentes
sellMain.prw (orquestrador)
/ | | | | \ \
/ | | | | \ \
sellCfg.prw | | | | sellRep.prw sellSta.prw
(config) | | | | (reprocesso) (monitor)
| | | |
sellQry.prw | | sellLog.prw
(extracao) | | (auditoria)
| |
sellBld.prw sellSnd.prw
(builder) (sender REST)
2. Convencoes de Nomenclatura
| Tipo | Declaracao | Chamada | Tamanho | Prefixo | Visibilidade |
|---|
| User Function | User Function SHSELL01() | U_SHSELL01() | 8 declarado, 10 chamada | SH obrigatorio | Publica (cross-PRW) |
| Static Function | Static Function SHCFGLOAD0() | interna ao PRW | exatamente 10 | SH obrigatorio | Privada (intra-PRW) |
Function | — | — | — | — | PROIBIDA |
Prefixos por componente: SHSELL (sellMain), SHCFG (sellCfg), SHQRY (sellQry),
SHBLD (sellBld), SHSEND (sellSnd), SHLOG (sellLog), SHREP (sellRep),
SHSTA (sellSta).
3. User Functions (13 total)
Todas possuem exatamente 8 caracteres na declaracao e sao chamadas com
prefixo U_ (10 caracteres na chamada).
3.1 SHSELL01 — Entry Point Manual de Vendas
| Atributo | Valor |
|---|
| Arquivo | sellMain.prw:15 |
| Parametros | cEmp (C), cFil (C), cDataIni (C), cDataFim (C), cTipoOper (C) |
| Retorno | Nil |
| Chamada | U_SHSELL01(cEmp, cFil, cDataIni, cDataFim, cTipoOper) |
Descricao: Ponto de entrada manual para execucao de vendas. Recebe empresa,
filial, periodo (AAAAMMDD) e tipo de operacao. Valida os parametros e delega
integralmente para a Static Function SHSELLEXEC().
Fluxo interno: SHSELL01 → SHSELLEXEC
3.2 SHSELL02 — Entry Point Manual de Devolucoes
| Atributo | Valor |
|---|
| Arquivo | sellMain.prw:480 |
| Parametros | aParam (A) — array {cEmp, cFil [, cDataIni, cDataFim]} |
| Retorno | Nil |
| Chamada | U_SHSELL02({cEmp, cFil, cDataIni, cDataFim}) |
Descricao: Ponto de entrada manual para execucao de devolucoes. Recebe um array
com no minimo empresa e filial (posicoes 1 e 2). Periodo e opcional (posicoes 3 e 4).
Extrai os valores e delega para SHSELLDEV0().
Fluxo interno: SHSELL02 → SHSELLDEV0
3.3 SHSELL03 — Schedule Vendas
| Atributo | Valor |
|---|
| Arquivo | sellMain.prw:513 |
| Parametros | aParam (A) — array {cEmp, cFil} |
| Retorno | Nil |
| Chamada | U_SHSELL03({cEmp, cFil}) |
Descricao: Funcao destinada ao Schedule nativo do Protheus para execucao
automatica apenas de vendas. Gerencia o ambiente RPC internamente:
- Verifica se
cEmpAnt ja existe; se nao, abre via RpcSetType(3) + RpcSetEnv.
- Fallback defensivo para
cEmp="01" e cFil="18" se parametros vazios.
- Chama
U_SHSELL01(cEmp, cFil, "", "", "V").
- Fecha RPC via
RpcClearEnv() apenas se abriu.
Fluxo interno: SHSELL03 → U_SHSELL01 → SHSELLEXEC
3.4 SHSELL04 — Schedule Devolucoes
| Atributo | Valor |
|---|
| Arquivo | sellMain.prw:569 |
| Parametros | aParam (A) — array {cEmp, cFil} |
| Retorno | Nil |
| Chamada | U_SHSELL04({cEmp, cFil}) |
Descricao: Estrutura identica a SHSELL03, porem para apenas devolucoes.
Chama U_SHSELL02({cEmp, cFil, "", ""}).
Fluxo interno: SHSELL04 → U_SHSELL02 → SHSELLDEV0
3.5 SHSELL05 — Schedule Principal (Vendas + Devolucoes)
| Atributo | Valor |
|---|
| Arquivo | sellMain.prw:625 |
| Parametros | aParam (A) — array {cEmp, cFil} |
| Retorno | Nil |
| Chamada | U_SHSELL05({cEmp, cFil}) |
Descricao: Funcao MAIN de Schedule. Executa ambos os fluxos em sequencia:
primeiro vendas (U_SHSELL01), depois devolucoes (U_SHSELL02).
Tratamento defensivo de parametros:
- Tenta extrair
cEmp/cFil do array aParam.
- Se falhar, tenta fallback para
cEmpAnt/cFilAnt (ambiente ja aberto).
- Se ainda vazio, hard-fallback para
cEmp="01" e cFil="18".
- Abre RPC apenas se
cEmpAnt nao existir; fecha apenas se abriu.
Fluxo interno: SHSELL05 → U_SHSELL01 (vendas) → U_SHSELL02 (devolucoes)
3.6 SHSELL06 — Fachada do Configurador
| Atributo | Valor |
|---|
| Arquivo | sellCfg.prw:12 |
| Parametros | cOper (C), aParams (A) |
| Retorno | Variant (depende da operacao) |
| Chamada | U_SHSELL06(cOper, aParams) |
Descricao: Fachada publica do componente de configuracao. Suporta 4 operacoes:
| Operacao | Static chamada | Parametros | Retorno |
|---|
"LOAD" | SHCFGLOAD0 | {cEmp, cFil, lPrimeiraCarga} | JsonObject com oCred e aPer |
"SAVE" | SHCFGSAVE0 | {cEmp, cFil, dData} | Logical — resultado do PutMv |
"OPEN" | SHCFGSETE0 | {cEmp, cFil} | Array {lAbriu, lOK} |
"CLOSE" | SHCFGCLSE0 | {lAbriu} | Nil |
MVs lidos: ES_SELLFST (primeira carga), ES_SELLMAXD (dias para carga full).
| Atributo | Valor |
|---|
| Arquivo | sellQry.prw:12 |
| Parametros | cOper (C), aParams (A) |
| Retorno | Variant |
| Chamada | U_SHSELL07(cOper, aParams) |
Descricao: Fachada publica do componente de extracao/consulta. Suporta 3 operacoes:
| Operacao | Static chamada | Parametros | Retorno |
|---|
"QUERY" | SHQRYGETN0 | {cEmp, cFil, cDataIni, cDataFim, cTipoOper} | Character — alias aberto |
"DEVQUERY" | SHQRYGETD0 | {cEmp, cFil, cDataIni, cDataFim} | Character — alias aberto |
"CLOSE" | SHQRYCLOS0 | {cAlias} | Nil |
QUERY: Abre consulta em SF2/SD2 (vendas) com anti-join ZRM.
DEVQUERY: Abre consulta em SF1/SD1 (devolucoes) com anti-join ZRM.
CLOSE: Fecha o alias com seguranca via DbCloseArea().
| Atributo | Valor |
|---|
| Arquivo | sellBld.prw:14 |
| Parametros | cOper (C), aParams (A) |
| Retorno | Variant |
| Chamada | U_SHSELL08(cOper, aParams) |
Descricao: Fachada publica do componente de transformacao. Suporta 2 operacoes:
| Operacao | Static chamada | Parametros | Retorno |
|---|
"GROUP" | SHBLDAGRN0 | {cAlias} | Array de JsonObject agrupados |
"BUILD" | SHBLDCAB00 | {oGrupo, cEmp, cFil} | JsonObject — payload JSON de 21 campos |
GROUP: Percorre o alias e agrupa linhas por DOC + SERIE, gerando array de grupos com cabecalho e array de itens.
BUILD: Monta o payload JSON final com 21 campos de cabecalho + array de itens (14 campos cada).
3.9 SHSELL09 — Fachada do Sender REST
| Atributo | Valor |
|---|
| Arquivo | sellSnd.prw:5 |
| Parametros | cOper (C), aParams (A) |
| Retorno | Variant |
| Chamada | U_SHSELL09(cOper, aParams) |
Descricao: Fachada publica do componente de envio REST. Suporta 2 operacoes:
| Operacao | Static chamada | Parametros | Retorno |
|---|
"SEND" | SHSENDENV0 | {oPayload, oCred} | Array {nStatus, cResposta, lSucesso} |
"POSTUPDATE" | SHSENDPOS0 | {oCred} | Logical |
Detalhes do SEND:
- Endpoint:
/PRTNotaVenda/grupo/{IdGrupo}/empresa/{idFilial}/CreateNotaVenda
- Autenticacao:
Authorization: Basic {Token}
- Retry: ate
ES_SELLRETR tentativas (default 3).
- HTTP 200-299: sucesso. HTTP 409: sucesso funcional (nota ja cadastrada).
- HTTP 400: erro irrecuperavel — interrompe retry.
- Fallback textual: detecta "NOTA" + "CADASTRADA" na resposta mesmo se
oRest:Post() falhar.
- Usa
HTTPGetStatus(@cError) e DecodeUTF8() para tratamento da resposta.
Detalhes do POSTUPDATE:
- Endpoint:
/PRTNotaVenda/grupo/{IdGrupo}/PostAtualizaNotaVenda
- Notifica o CRM para processar recebimentos apos integracao.
3.10 SHSELL10 — Fachada do Logger/Auditor
| Atributo | Valor |
|---|
| Arquivo | sellLog.prw:4 |
| Parametros | cOper (C), aParams (A) |
| Retorno | Variant |
| Chamada | U_SHSELL10(cOper, aParams) |
Descricao: Fachada publica do componente de auditoria. Suporta 1 operacao:
| Operacao | Static chamada | Parametros | Retorno |
|---|
"WRITE" | SHLOGGRAV0 | {oPayload, cDoc, cSerie, cEmp, cFil, nStatus, cResposta} | Nil |
Grava um registro na tabela ZRM para cada nota processada, com os campos
detalhados na Secao 6.
3.11 SHSELL11 — Auditor de Console
| Atributo | Valor |
|---|
| Arquivo | sellSta.prw:14 |
| Parametros | dDataIni (D), dDataFim (D), cTipo (C), cEmp (C), cFil (C) |
| Retorno | Numeric — total de registros encontrados |
| Chamada | U_SHSELL11(dDataIni, dDataFim, cTipo, cEmp, cFil) |
Descricao: Monitor de auditoria via console (ConOut). Consulta a tabela ZRM
por periodo, empresa, filial e tipo (V=Venda, D=Devolucao, A=Ambos).
Exibe os registros formatados com numero sequencial, chave, documento, serie,
status, atualizacao e tentativas. Retorna o total de registros encontrados.
Query SQL: LEFT JOIN na ZRM com filtros por ZRM_INTERF = 'SELL-POST',
ZRM_DTDIGIT (periodo), ZRM_CODIGO (emp/fil via LIKE), ZRM_OPERAC (tipo).
3.12 SHSELL12 — Monitor Grafico (FWMBrowse)
| Atributo | Valor |
|---|
| Arquivo | sellSta.prw:122 |
| Parametros | Nenhum |
| Retorno | Nil |
| Chamada | U_SHSELL12() |
Descricao: Tela grafica de monitoramento utilizando FWMBrowse. Abre um browse
sobre a tabela ZRM com filtro padrao ZRM_INTERF == 'SELL-POST' e legenda colorida:
| Condicao | Cor | Significado |
|---|
ZRM_STATUS == '200' .Or. ZRM_STATUS == '201' | Verde | Integrado com Sucesso |
ZRM_STATUS == '409' | Amarelo | Nota Ja Existente |
Val(ZRM_STATUS) >= 400 .And. ZRM_STATUS != '409' | Vermelho | Erro de Integracao |
3.13 SHSELL13 — Reprocessador
| Atributo | Valor |
|---|
| Arquivo | sellRep.prw:13 |
| Parametros | cOper (C), aParams (A) |
| Retorno | Numeric — quantidade de notas marcadas |
| Chamada | U_SHSELL13(cOper, aParams) |
Descricao: Fachada publica do componente de reprocessamento. Suporta 1 operacao:
| Operacao | Static chamada | Parametros | Retorno |
|---|
"MARK" | SHREPMARC0 | {cEmp, cFil} | Numeric |
Percorre registros ZRM pendentes (ZRM_ATUALI = 'N', ZRM_INTERF = 'SELL-POST',
ZRM_OPERAC IN ('A','D'), ZRM_TENTAT < nMaxRetry). Para cada registro:
- Se
nTent >= 10: marca como erro permanente (ZRM_OPERAC = 'E', ZRM_ATUALI = 'S').
- Senao: marca para retry (
ZRM_OPERAC = 'R', ZRM_ATUALI = ' ').
- Incrementa
ZRM_TENTAT.
Abre e fecha ambiente RPC via U_SHSELL06("OPEN"/"CLOSE").
4. Static Functions (27 total)
Todas possuem exatamente 10 caracteres e visibilidade restrita ao proprio PRW.
4.1 sellMain.prw (2 funcoes)
| Funcao | Linha | Descricao |
|---|
SHSELLEXEC | 31 | Orquestrador de vendas. Abre ambiente RPC, carrega configuracao, executa query (QUERY), agrupa resultados (GROUP), para cada grupo constroi payload (BUILD), envia (SEND) e audita (WRITE). Salva data da ultima execucao e desmarca flag de primeira carga. Tratamento de erro com Begin Sequence/Recover. |
SHSELLDEV0 | 243 | Orquestrador de devolucoes. Estrutura analoga a SHSELLEXEC, porem utilizando DEVQUERY (SF1/SD1) no lugar de QUERY (SF2/SD2). Nao recebe cTipoOper — o tipo e intrinseco a devolucao. |
4.2 sellCfg.prw (8 funcoes)
| Funcao | Linha | Descricao |
|---|
SHCFGVALP0 | 39 | Validador de parametros. Verifica se aParam e um array com pelo menos 2 elementos Character nao vazios (empresa e filial). Retorna Logical. |
SHCFGSETE0 | 62 | Abertura de ambiente RPC. Se cEmpAnt/cFilAnt ja existem, apenas retorna {lAbriu=.F., lOK=.T.}. Senao, executa RpcSetType(3) + RpcSetEnv() e retorna {lAbriu=.T., lOK}. Excecao DA03: Type('cEmpAnt') permitido exclusivamente aqui. |
SHCFGCLSE0 | 88 | Fechamento de ambiente RPC. Executa RpcClearEnv() apenas se lAbriu = .T. (quem abre, fecha). |
SHCFGGETC0 | 103 | Obtencao de credenciais. Chama U_crmCredl(cEmp, "seller") e valida se o objeto retornado possui Url, Token e IdGrupo nao vazios. Retorna JsonObject ou Nil. |
SHCFGLOAD0 | 131 | Carga do contexto consolidado. Cria JsonObject com duas propriedades: oCred (via SHCFGGETC0) e aPer (via SHCFGGETP0). Retorna o objeto ou Nil. |
SHCFGGETP0 | 153 | Calculo de periodo. Se lPrimeiraCarga, retroage ES_SELLMAXD dias (default 720). Senao, usa a data da ultima execucao (SHCFGGETU0); se vazia, fallback para carga full. Retorna {cDataIni, cDataFim} em AAAAMMDD. |
SHCFGGETU0 | 189 | Leitura da ultima execucao. Le o MV ES_SELLULT_{emp}_{fil} via SuperGetMv. Retorna Date ou data vazia. |
SHCFGSAVE0 | 209 | Gravacao da ultima execucao. Grava dData no MV ES_SELLULT_{emp}_{fil} via PutMv. Retorna Logical. |
4.3 sellQry.prw (3 funcoes)
| Funcao | Linha | Descricao |
|---|
SHQRYGETN0 | 43 | Query de vendas (SF2/SD2). Monta SQL com INNER JOIN SF2→SD2→SA1→SF4→SB1, LEFT JOIN SA3 (vendedor) e LEFT JOIN ZRM (anti-join). Filtros: F2_TIPO = 'N', F4_XRESMOV LIKE '%VEND%' (venda) ou LIKE '%DEVVEN%' (cTipoOper='D'), A1_XEMPGRU <> '1', F2_XFILORI, periodo por F2_EMISSAO. Anti-join: ZRM_CODIGO IS NULL (chave composta: doc+serie+emp+fil). Retorna alias aberto ou string vazia. |
SHQRYGETD0 | 202 | Query de devolucoes (SF1/SD1). Monta SQL com FROM SD1 → INNER JOIN SF1→SA1→SF4→SB1, LEFT JOIN ZRM. Filtros: D1_TIPO = 'D', F4_XRESMOV = 'DEVVEN' (exato), D1_TP = 'ME', D1_XEMPFIL = '.', A1_XEMPGRU <> '1', periodo por D1_DTDIGIT. Join SA1 por F1_FORNECE. Vendedor (SA3) ausente — campos retornam ''. DESCONTO/ACRESCIMO fixos em 0. Preco unitario: D1_VUNIT. Anti-join identico ao de vendas. |
SHQRYCLOS0 | 184 | Fechamento de alias. Verifica se cAlias e valido (Select(cAlias) > 0) e executa DbCloseArea(). |
4.4 sellBld.prw (8 funcoes)
| Funcao | Linha | Descricao |
|---|
SHBLDAGRN0 | 38 | Agrupador de linhas. Percorre o alias da query e agrupa por DOC + SERIE. Para cada novo grupo, extrai 15 campos de cabecalho (cDoc, cSerie, dEmissao, cCliente, cLoja, nValBrut, nValMerc, cNomeCli, cCgcCli, cVendId, cVendNome, cTes, cTesTexto, cXresmov, cChvNfe) e inicia array de itens. Cada linha gera um item via SHBLDITEM0. Retorna array de JsonObject. |
SHBLDCAB00 | 112 | Montador de payload JSON. Recebe um grupo (oGrupo) + contexto (cEmp, cFil). Constroi JsonObject com 21 campos: idNota, idEmpresa, idFilial, clienteId, numeroNota, serie, data (ISO 8601 via SHBLDFMTD0), operacao, operacaoNatureza, tipoOperacao (via SHBLDCLSO0), Moeda, totalMercadoria, totalServico, totalNota, tipoPagamento (via SHBLDTIPP0), nroParcelas (via SHBLDCNTP0), vendedorId, vendedorNome, customerName, customerDoc, listaItens. |
SHBLDITEM0 | 156 | Montador de item. Le os campos do alias atual (DOC, ITEM, CODIGO, DESCRICAO, NCM, CFOP, CLASSE, UM, QUANTIDADE, PRECO_UNIT, TOTAL_ITEM, DESCONTO, ACRESCIMO, IMPOSTOS). Constroi JsonObject com 14 campos: idLancamento, idNotaItem, codigoProduto, descricaoProduto, ncm, cfop, tipo (via SHBLDCLSP0), moeda, unidade, quantidade, precoUnitario, precoTotal, descontos, acrescimos, impostos. |
SHBLDCLSP0 | 186 | Classificador de produto. Mapeia B1_XCLASSE para tipo: "001"/"122"/"126"/"128" → "ME", "336"/"532" → "SE", "614"–"619" → "MA", default → "O". |
SHBLDCLSO0 | 216 | Classificador de operacao. Detecta "DEVVEN" em F4_XRESMOV para retornar "D" (devolucao); caso contrario "V" (venda). |
SHBLDFMTD0 | 234 | Formatador de data ISO 8601. Converte Date Protheus para string AAAA-MM-DD T00:00:00-03:00. |
SHBLDTIPP0 | 255 | Tipo de pagamento. Consulta SE1 (E1_VENCTO) para o documento. Se existe vencimento, retorna "P" (prazo); senao "V" (vista). |
SHBLDCNTP0 | 307 | Contador de parcelas. Consulta SE1 com COUNT(DISTINCT E1_PARCELA) para o documento. Retorna o total (minimo 1). |
4.5 sellSnd.prw (2 funcoes)
| Funcao | Linha | Descricao |
|---|
SHSENDENV0 | 21 | Envio REST da nota. Extrai Url, Token, IdGrupo das credenciais. Monta endpoint /PRTNotaVenda/grupo/{IdGrupo}/empresa/{idFilial}/CreateNotaVenda. Loop de retry ate ES_SELLRETR tentativas: envia POST com FWRest, avalia HTTPGetStatus. Sucesso: 200-299 ou 409. Erro 400: interrompe. Fallback textual para 409 na resposta. Retorna {nStatus, cResposta, lSucesso}. |
SHSENDPOS0 | 138 | Notificacao pos-integracao. Envia POST para /PRTNotaVenda/grupo/{IdGrupo}/PostAtualizaNotaVenda. Retorna Logical (sucesso se HTTP 200). |
4.6 sellLog.prw (3 funcoes)
| Funcao | Linha | Descricao |
|---|
SHLOGGRAV0 | 19 | Gravacao de auditoria ZRM. Recebe payload, chave do documento e resultado do envio. Monta cChaveDoc = doc/serie (padded), cStatus = nStatus (padded). Executa RecLock("ZRM", .T.) e grava 9 campos nativos + 3 campos opcionais com FieldPos(). Usa FwTimeUF('SP') para ZRM_DATA/ZRM_HORA. |
SHLOGMKCH0 | 52 | Montador de chave composta. Concatena RTrim(cDoc) + RTrim(cSerie) + AllTrim(cEmp) + AllTrim(cFil). |
SHLOGMASC0 | 65 | Mascarador de dados pessoais. Cria copia mascarada: NOME_CLI → primeiros 3 chars + "***"; CGC_CLI → "***" + ultimos 4 chars. (Implementado, nao chamado diretamente por SHLOGGRAV0 — disponivel para uso futuro.) |
4.7 sellRep.prw (1 funcao)
| Funcao | Linha | Descricao |
|---|
SHREPMARC0 | 36 | Marcador de reprocessamento. Abre ambiente RPC, consulta ZRM por registros com ZRM_INTERF='SELL-POST', ZRM_ATUALI='N', ZRM_OPERAC IN ('A','D'), ZRM_TENTAT < nMaxRetry. Para cada registro: se nTent >= 10, marca como erro (OPERAC='E', ATUALI='S'); senao marca para retry (OPERAC='R', ATUALI=' '). Incrementa ZRM_TENTAT. Fecha ambiente RPC. Retorna contagem de registros processados. |
5. MVs (Parametros do Modulo)
| MV | Tipo | Default | Descricao |
|---|
ES_SELLFST | Logico | .F. | Flag de primeira carga. Quando .T., o sistema retroage ES_SELLMAXD dias para carga inicial completa. Alterado para .F. apos primeira execucao bem-sucedida. |
ES_SELLMAXD | Numerico | 720 | Dias maximos para carga full. Usado quando lPrimeiraCarga = .T. ou quando a data da ultima execucao esta indisponivel. |
ES_SELLRETR | Numerico | 3 | Numero maximo de tentativas de reenvio REST por nota. Usado por SHSENDENV0 (loop) e SHREPMARC0 (filtro de elegibilidade). |
ES_SELLULT_{emp}_{fil} | Data | Vazio | Data da ultima execucao bem-sucedida para a combinacao empresa+filial. Chave dinamica construida como ES_SELLULT_ + cEmp + _ + cFil. Exemplo: ES_SELLULT_01_18. |
6. Tabela ZRM — Estrutura de Campos
6.1 Campos Nativos (validados em producao)
Gravados diretamente por SHLOGGRAV0 (sellLog.prw:19):
| Campo | Tipo | Conteudo |
|---|
ZRM_FILIAL | Caractere | xFilial("ZRM") — filial do ambiente corrente |
ZRM_EMPRES | Caractere | cEmp — codigo logico da empresa |
ZRM_FILORI | Caractere | cFil — codigo logico da filial |
ZRM_INTERF | Caractere | "SELL-POST" — identificador fixo da interface Seller |
ZRM_CODIGO | Caractere | PadR(doc + "/" + serie, TamSX3("ZRM_CODIGO")[1]) — chave composta |
ZRM_STATUS | Caractere | PadR(cValToChar(nStatus), TamSX3("ZRM_STATUS")[1]) — HTTP status |
ZRM_DATA | Date | aTimeUf[1] — data da gravacao (fuso SP) |
ZRM_HORA | Caractere | aTimeUf[2] — hora da gravacao (fuso SP) |
ZRM_RESPON | Caractere | cResposta — corpo da resposta HTTP (pode conter JSON) |
6.2 Campos Opcionais (protegidos por FieldPos)
Gravados apenas se o campo existir no dicionario (SX3) do ambiente:
| Campo | Condicao | Conteudo |
|---|
ZRM_METODO | FieldPos("ZRM_METODO") > 0 | "/POST" — metodo HTTP utilizado |
ZRM_OPERAC | FieldPos("ZRM_OPERAC") > 0 | "A" — tipo de operacao (A=Alteracao/Inclusao) |
ZRM_ATUALI | FieldPos("ZRM_ATUALI") > 0 | "S" — flag de atualizacao (S=Sim) |
6.3 Campos Referenciados (nao gravados diretamente por SHLOGGRAV0)
Campos utilizados por outros componentes (sellRep, sellSta) — existencias
condicionadas ao ambiente de producao:
| Campo | Uso | Componente |
|---|
ZRM_TENTAT | Contador de tentativas de reprocessamento; incrementado por SHREPMARC0 | sellRep.prw |
ZRM_DTDIGIT | Data de digitacao; usado como filtro de periodo em SHSELL11 | sellSta.prw |
ZRM_XDOC | Documento (desnormalizado); consultado por SHSELL11 | sellSta.prw |
ZRM_XSERIE | Serie (desnormalizado); consultado por SHSELL11 | sellSta.prw |
Regra inviolavel: Nenhum agente esta autorizado a inferir ou criar nomes de
campos. Apenas campos validados no dicionario SX3 do cliente podem ser
referenciados. Campos nao nativos devem obrigatoriamente usar FieldPos().
7. Fluxo de Dados
7.1 Fluxo Principal (Vendas)
ZRM (anti-join)
│
▼
SHQRYGETN0 ─── Query SQL SF2/SD2 ─── alias aberto
│
▼
SHBLDAGRN0 ─── Agrupa linhas por DOC+SERIE ─── array de grupos
│
▼
SHBLDCAB00 ─── Monta JSON 21 campos ─── JsonObject payload
│
▼
SHSENDENV0 ─── POST REST Campos Dealer ─── {nStatus, cResposta, lSucesso}
│
▼
SHLOGGRAV0 ─── Grava auditoria ─── registro ZRM
7.2 Fluxo de Devolucoes
ZRM (anti-join)
│
▼
SHQRYGETD0 ─── Query SQL SF1/SD1 ─── alias aberto
│
▼
SHBLDAGRN0 ─── Agrupa linhas (mesmo Builder) ─── array de grupos
│
▼
SHBLDCAB00 ─── Monta JSON (mesmo contrato) ─── JsonObject payload
│
▼
SHSENDENV0 ─── POST REST ─── {nStatus, cResposta, lSucesso}
│
▼
SHLOGGRAV0 ─── Auditoria ZRM
7.3 Fluxo de Schedule (SHSELL05)
Schedule Protheus
│
▼
SHSELL05 (MAIN)
│
├── RpcSetType(3) / RpcSetEnv (se necessario)
│
├── U_SHSELL01 (vendas) ─── SHSELLEXEC ─── [fluxo 7.1]
│
├── U_SHSELL02 (devolucoes) ─── SHSELLDEV0 ─── [fluxo 7.2]
│
└── RpcClearEnv (se abriu)
7.4 Fluxo de Reprocessamento
SHSELL13 ("MARK")
│
▼
SHREPMARC0
│
├── Abre ambiente RPC (U_SHSELL06 "OPEN")
│
├── Query ZRM: ZRM_ATUALI='N', ZRM_TENTAT < ES_SELLRETR
│
├── Para cada registro:
│ ├── nTent < 10 → OPERAC='R', ATUALI=' '
│ └── nTent >= 10 → OPERAC='E', ATUALI='S'
│
└── Fecha RPC (U_SHSELL06 "CLOSE")
8. Decisoes Arquiteturais Vigentes
| # | Decisao | Impacto |
|---|
| DA01 | Separacao em 8 fontes por responsabilidade | Manutenibilidade e coesao |
| DA02 | Bloco 3 como base estrutural | Correcao de defeitos do Bloco 1 |
| DA03 | Parametros explicitos cEmp/cFil em todas as funcoes | Rastreabilidade; cEmpAnt apenas em Type() para deteccao |
| DA04 | HTTP 409 = sucesso funcional unificado | Nota duplicada nao e erro |
| DA05 | Mascaramento de dados pessoais (LGPD) | SHLOGMASC0 disponivel |
| DA06 | Filtro por F4_XRESMOV, sem F2_TIPO <> 'D' | Precisao na classificacao de operacao |
| DA07 | Chave ZRM composta: doc+serie+emp+fil | Unicidade no anti-join |
| DA08 | Transicao faseada (legado + novo coexistem) | Rollback seguro |
| DA09 | Query sem filtro B1_TIPO = 'ME' | Abrangencia de produtos |
| DA10 | Contador de tentativas acumuladas com limite de 10 | Previne loops infinitos |
Decisoes para Devolucoes
| # | Decisao | Impacto |
|---|
| DA11 | SF1/SD1 como origem de dados | Tabelas corretas para NF de entrada |
| DA12 | Query com mesmos aliases de vendas | Builder 100% reutilizavel |
| DA13 | SA3 ausente (SF1 nao possui vendedor) | Campos VENDEDOR/NOME_VEND vazios |
| DA14 | Join SA1 por F1_FORNECE | Cliente correto para devolucao |
| DA15 | D1_TIPO = 'D' como identificador | Filtro exato de devolucao |
| DA16 | F4_XRESMOV = 'DEVVEN' com match exato | Sem ambiguidade com LIKE |
| DA18 | SD1 como tabela principal (FROM SD1 → JOIN SF1) | Performance e semantica |
| DA19 | D1_XEMPFIL = '.' como filtro de origem | Exclui cross-company |
| DA20 | D1_TP = 'ME' como filtro de tipo | Apenas mercadorias |
9. Estrutura do Payload JSON
9.1 Cabecalho (21 campos) — SHBLDCAB00
| Campo JSON | Origem | Descricao |
|---|
idNota | cDoc | Numero do documento |
idEmpresa | cEmp | Codigo logico da empresa |
idFilial | cFil | Codigo logico da filial |
clienteId | cCliente | Codigo do cliente |
numeroNota | cDoc | Numero do documento (replicado) |
serie | cSerie | Serie do documento |
data | dEmissao (formatado ISO 8601) | Data de emissao |
operacao | cTes | Codigo TES |
operacaoNatureza | cTesTexto | Descricao do TES |
tipoOperacao | SHBLDCLSO0(cXresmov) | "V" ou "D" |
Moeda | Fixo "BRL" | Moeda |
totalMercadoria | nValMerc | Valor total de mercadorias |
totalServico | Fixo "0" | Valor total de servicos |
totalNota | nValBrut | Valor total da nota |
tipoPagamento | SHBLDTIPP0(...) | "P" (prazo) ou "V" (vista) |
nroParcelas | SHBLDCNTP0(...) | Quantidade de parcelas |
vendedorId | cVendId | Codigo do vendedor |
vendedorNome | cVendNome | Nome do vendedor |
customerName | cNomeCli | Nome do cliente |
customerDoc | cCgcCli | CPF/CNPJ do cliente |
listaItens | aItens | Array de itens (14 campos cada) |
9.2 Item (14 campos) — SHBLDITEM0
| Campo JSON | Origem | Descricao |
|---|
idLancamento | DOC + ITEM | Chave composta do lancamento |
idNotaItem | ITEM (zero-filled 3 digitos) | Numero do item |
codigoProduto | CODIGO | Codigo do produto |
descricaoProduto | DESCRICAO | Descricao do produto |
ncm | NCM | Codigo NCM |
cfop | CFOP | Codigo CFOP |
tipo | SHBLDCLSP0(CLASSE) | "ME", "SE", "MA" ou "O" |
moeda | Fixo "BRL" | Moeda |
unidade | UM | Unidade de medida |
quantidade | QUANTIDADE | Quantidade |
precoUnitario | PRECO_UNIT | Preco unitario |
precoTotal | TOTAL_ITEM | Preco total do item |
descontos | DESCONTO | Valor de desconto |
acrescimos | ACRESCIMO | Valor de acrescimo |
impostos | IMPOSTOS | Valor de impostos |
9.3 Diferencas Devolucoes vs Vendas
| Aspecto | Vendas (SF2/SD2) | Devolucoes (SF1/SD1) |
|---|
| Tabela cabecalho | SF2 | SF1 |
| Tabela itens | SD2 | SD1 |
| Cliente | F2_CLIENTE / F2_LOJA | F1_FORNECE / F1_LOJA |
| Vendedor | SA3 (F2_VEND1) | Ausente (campos vazios) |
| Preco unitario | D2_PRCVEN | D1_VUNIT |
| Desconto/Acrescimo | D2_DESCON / D2_VALACRS | Fixo 0 |
| Data periodo | F2_EMISSAO | D1_DTDIGIT |
| Filtro tipo | F2_TIPO = 'N' | D1_TIPO = 'D' |
| Filtro TES | F4_XRESMOV LIKE '%VEND%' | F4_XRESMOV = 'DEVVEN' |
| Filtros adicionais | — | D1_TP = 'ME', D1_XEMPFIL = '.' |
10. Tratamento de Erros
10.1 Orquestrador (sellMain)
Begin Sequence / Recover Using oErro em dois niveis: nota individual e filial.
- Erro em nota: loga via
ConOut, continua processando proximas notas.
- Erro em filial: loga e encerra fluxo daquela filial.
- Objeto de erro inspecionado para
ValType == "J" vs "O" com fallback para Description/description.
- Alias de query sempre fechado no final, mesmo em caso de erro (
If !Empty(cAlias)).
10.2 Sender REST (sellSnd)
- Retry loop com maximo
ES_SELLRETR tentativas.
- HTTP 400: interrompe imediatamente (erro de schema/validacao).
- HTTP 409: tratado como sucesso (nota ja existe).
- Fallback textual: detecta "NOTA" + "CADASTRADA" na resposta mesmo se
oRest:Post() falhar.
DecodeUTF8() com code page cp1252 para caracteres acentuados.
10.3 Logger (sellLog)
RecLock("ZRM", .T.) — lock otimista; se falhar, operacao e ignorada silenciosamente.
FieldPos() protege campos customizados — se o campo nao existir no ambiente, a atribuicao e ignorada.
10.4 Query (sellQry)
- Validacao de todos os parametros antes da montagem SQL (
ValType, Empty, AllTrim).
StrTran(..., "'", "''") em todos os valores concatenados na SQL (protecao contra SQL injection).
TCSetField para fixar tipo Date no campo EMISSAO.
ConOut de diagnostico com dados de contexto em caso de falha.
11. Ambiente RPC
11.1 Regras
| Regra | Descricao |
|---|
RpcSetType(3) | Nao consome licenca de usuario |
| Quem abre, fecha | CfgSetEnv retorna {lAbriu, lOK}; RpcClearEnv apenas se lAbriu = .T. |
| Excecao DA03 | Apenas CfgSetEnv pode usar Type('cEmpAnt') e Type('cFilAnt') para deteccao |
| Multi-empresa | xFilial("SA1"), xFilial("SB1"), xFilial("SF4") usam prefixo correto |
11.2 Ciclo de Vida
SHCFGSETE0 ─── abre RPC (se necessario) ─── {lAbriu, lOK}
│
▼
[fluxo de processamento]
│
▼
SHCFGCLSE0 ─── fecha RPC (se lAbriu)
11.3 Funcoes de Schedule (SHSELL03/04/05)
Gerenciam RPC internamente (nao dependem de SHCFGSETE0/SHCFGCLSE0):
- Abrem apenas se
cEmpAnt nao existe.
- Fecham apenas se abriram (
lRpc = .T.).
- Fallback defensivo:
cEmp="01", cFil="18".
12. Mapeamento de Chamadas entre Componentes
SHSELL01 ──► SHSELLEXEC
├── U_SHSELL06("OPEN")
├── U_SHSELL06("LOAD") ──► SHCFGLOAD0 ──► SHCFGGETC0, SHCFGGETP0
├── U_SHSELL07("QUERY") ──► SHQRYGETN0
├── U_SHSELL08("GROUP") ──► SHBLDAGRN0
├── U_SHSELL08("BUILD") ──► SHBLDCAB00 ──► SHBLDFMTD0, SHBLDCLSO0,
│ SHBLDTIPP0, SHBLDCNTP0
├── U_SHSELL09("SEND") ──► SHSENDENV0
├── U_SHSELL10("WRITE") ──► SHLOGGRAV0
├── U_SHSELL06("SAVE") ──► SHCFGSAVE0
├── U_SHSELL07("CLOSE") ──► SHQRYCLOS0
├── U_SHSELL09("POSTUPDATE") ──► SHSENDPOS0
└── U_SHSELL06("CLOSE") ──► SHCFGCLSE0
SHSELL02 ──► SHSELLDEV0
└── (mesmo fluxo, "DEVQUERY" no lugar de "QUERY")
SHSELL03 ──► U_SHSELL01 (vendas, gerencia RPC internamente)
SHSELL04 ──► U_SHSELL02 (devolucoes, gerencia RPC internamente)
SHSELL05 ──► U_SHSELL01 + U_SHSELL02 (ambos, gerencia RPC internamente)
SHSELL13 ──► SHREPMARC0
├── U_SHSELL06("OPEN")
├── (query e update ZRM direto)
└── U_SHSELL06("CLOSE")
SHSELL11 ──► (query ZRM direta + ConOut)
SHSELL12 ──► (FWMBrowse direto sobre ZRM)
13. Estrutura de Diretorios
fontes/_ag/crm/seller/
├── sellMain.prw (675 linhas) — Orquestrador: 5 User + 2 Static
├── sellCfg.prw (218 linhas) — Configurador: 1 User + 8 Static
├── sellQry.prw (314 linhas) — Extrator: 1 User + 3 Static
├── sellBld.prw (346 linhas) — Builder: 1 User + 8 Static
├── sellSnd.prw (207 linhas) — Sender REST: 1 User + 2 Static
├── sellLog.prw (104 linhas) — Logger/Auditor: 1 User + 3 Static
├── sellRep.prw (128 linhas) — Reprocessador: 1 User + 1 Static
└── sellSta.prw (138 linhas) — Monitor: 2 User + 0 Static
Total: 13 User Functions + 27 Static Functions = 40 funcoes.
14. Glossario de Siglas
| Sigla | Significado |
|---|
| DA | Decisao Arquitetural |
| MV | Matriz de Variaveis (parametros do Protheus) |
| RPC | Remote Procedure Call (ambiente Protheus) |
| SF1 | Tabela de NF de Entrada (cabecalho) |
| SD1 | Tabela de Itens de NF de Entrada |
| SF2 | Tabela de NF de Saida (cabecalho) |
| SD2 | Tabela de Itens de NF de Saida |
| SA1 | Cadastro de Clientes/Fornecedores |
| SA3 | Cadastro de Vendedores |
| SB1 | Cadastro de Produtos |
| SF4 | Cadastro de TES (Tipos de Entrada/Saida) |
| SE1 | Contas a Receber/Pagar |
| ZRM | Tabela de Auditoria/Log de Integracao |
| TES | Tipo de Entrada e Saida (natureza fiscal) |
| NCM | Nomenclatura Comum do Mercosul |
| CFOP | Codigo Fiscal de Operacoes e Prestacoes |
Documento gerado em 06/08/2026. Release Seller v1.1.0.